////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_MUTEX_H__
#define __WN_MUTEX_H__

#include "WNCore/inc/WNBase.h"

#ifdef _WN_WINDOWS
    #include <windows.h>

    typedef HANDLE WN_MUTEX_T;
#elif defined _WN_LINUX
    #include <pthread.h>

    typedef pthread_mutex_t WN_MUTEX_T;
#endif

__WN_INLINE WN_VOID WNMutexInitialize(WN_MUTEX_T* _mutex);
__WN_INLINE WN_VOID WNMutexDestroy(WN_MUTEX_T* _mutex);
__WN_INLINE WN_VOID WNMutexLock(WN_MUTEX_T* _mutex);
__WN_INLINE WN_VOID WNMutexUnlock(WN_MUTEX_T* _mutex);

#ifdef _WN_CPLUSPLUS
    class WNMutexScopeLock;

    class WNMutex {
    public:
        __WN_INLINE WNMutex();
        __WN_INLINE ~WNMutex();

        __WN_INLINE WN_VOID Lock();
        __WN_INLINE WN_VOID Unlock();

    private:
        friend class WNMutexScopeLock;

    private:
        WN_MUTEX_T mMutex;
    };

    class WNMutexScopeLock {
    public:
        __WN_INLINE WNMutexScopeLock(WN_MUTEX_T* _mutex);
        __WN_INLINE WNMutexScopeLock(WNMutex& _mutex);
        __WN_INLINE ~WNMutexScopeLock();

    private:
        WNMutexScopeLock() {}

    private:
        WN_MUTEX_T* mMutex;
    };

    #define WN_MUTEX_SCOPE_LOCK(_mutex) WNMutexScopeLock lock__COUNTER____LINE__(_mutex)
#endif

#include "WNConcurrency/inc/WNMutex.inl"

#endif // __WN_MUTEX_H__